package com.njcb.ams.store.esbmodule.interceptor;

import com.njcb.ams.repository.entity.SysTradeLog;
import com.njcb.ams.pojo.enumvalue.TransStatusCode;
import com.njcb.ams.service.LogManageService;
import com.njcb.ams.store.esbmodule.Constants;
import com.njcb.ams.store.esbmodule.EsbHeadUtil;
import com.njcb.ams.store.esbmodule.SysHeadBean;
import com.njcb.ams.support.exception.ExceptionUtil;
import com.njcb.ams.util.AmsBeanUtils;
import com.thoughtworks.xstream.XStream;
import org.apache.commons.lang.StringUtils;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.MessageContentsList;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.service.Service;
import org.apache.cxf.service.invoker.MethodDispatcher;
import org.apache.cxf.service.model.BindingOperationInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author CXF响应拦截器
 */
@Component
public class RspInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
	private static final Logger logger = LoggerFactory.getLogger(RspInterceptor.class);
	
	@Autowired
	private LogManageService logManageService;
	
	private static XStream xStream = new XStream();
	public RspInterceptor() {
		super(Phase.PRE_INVOKE);
	}
	
	public RspInterceptor(String phase) {
		super(phase);
	}

	@Override
	public void handleMessage(SoapMessage message) {
		Exchange exchange = message.getExchange();
		BindingOperationInfo bp = exchange.get(BindingOperationInfo.class);
		SysTradeLog tradeLog = (SysTradeLog) bp.getProperty(Constants.CXF_LOG_STORAGE_PROPERTY);
		long useTime = System.currentTimeMillis() - tradeLog.getTimeStamp();
		tradeLog.setUseTime(useTime);
		Service service = exchange.get(Service.class);
		MethodDispatcher m = (MethodDispatcher) service.get(MethodDispatcher.class.getName());
		Method method = m.getMethod(bp);
		MessageContentsList list = MessageContentsList.getContentsList(message);
		Class<?>[] parameterTypes = method.getParameterTypes();
		if (parameterTypes.length == 1) {
			Object param = list.get(0);
			logger.info("\n返回报文\n" + xStream.toXML(param));
			SysHeadBean sysHeadBean = new SysHeadBean();
			Method getReqSysHead = null;
			Object rspSysHead = null;
			try {
				try {
					if(null == param){
						throw new NoSuchMethodException("param为空");
					}
					getReqSysHead = param.getClass().getDeclaredMethod("getRspSysHead");
				} catch (NoSuchMethodException e) {
					logger.warn("未遵循南京银行ESB规范,没有ESB头信息");
					if (null != logManageService) {
						logManageService.saveLog(tradeLog);
					}
					return;
				}
				rspSysHead = getReqSysHead.invoke(param);
				AmsBeanUtils.copyProperties(sysHeadBean, rspSysHead);
			} catch (Exception e) {
				ExceptionUtil.printStackTrace(e);
				tradeLog.setTransStatus(TransStatusCode.EROR.getCode());
				tradeLog.setRetMsg("[" + e.getClass().getSimpleName() + "]" + e.getMessage());
				if (null != logManageService) {
					logManageService.saveLog(tradeLog);
				}
				ExceptionUtil.throwAppException(e.getMessage());
			}

			try {
				if(EsbHeadUtil.getIsHeadProxy()){
					if (StringUtils.isNotEmpty(sysHeadBean.getTransStatus())) {
						if (!TransStatusCode.SUCC.getCode().equals(sysHeadBean.getTransStatus())) {
							logger.error("交易处理异常：交易标志=" + sysHeadBean.getTransStatus() + " , 错误码=" + sysHeadBean.getRetCode() + " , 错误消息=" + sysHeadBean.getRetMsg());
							tradeLog.setTransStatus(TransStatusCode.FAIL.getCode());
							tradeLog.setRetMsg(sysHeadBean.getRetMsg());
							ExceptionUtil.throwAppException(sysHeadBean.getRetMsg(), sysHeadBean.getRetCode());
						}
					} else if (StringUtils.isNotEmpty(sysHeadBean.getRetCode())) {
						if (!TransStatusCode.SUCC.getCode().equals(sysHeadBean.getRetCode())) {
							logger.error("交易处理异常：错误码=" + sysHeadBean.getRetCode() + " , 错误消息=" + sysHeadBean.getRetMsg());
							tradeLog.setTransStatus(TransStatusCode.FAIL.getCode());
							tradeLog.setRetMsg(sysHeadBean.getRetMsg());
							ExceptionUtil.throwAppException(sysHeadBean.getRetMsg(), sysHeadBean.getRetCode());
						}
					} else {
						logger.error("交易处理异常：返回报文无交易成功标志及返回码");
						tradeLog.setTransStatus(TransStatusCode.FAIL.getCode());
						tradeLog.setRetMsg(sysHeadBean.getRetMsg());
						ExceptionUtil.throwAppException("返回报文无交易成功标志及返回码");
					}
				}else{
					EsbHeadUtil.setIsHeadProxy(true);
				}

			} finally {
				if (null != logManageService) {
					tradeLog.setTransSeq(sysHeadBean.getRespSeq());
					logManageService.saveLog(tradeLog);
				}
			}

		}

	}

}
